﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace Transformer.iHunter.Plugins.BBS
{
    public abstract class Task
    {
        public enum Type
        {
            None = 0,
            CreateThread,
            ReplyPost,
            DownloadPosts,
            DownloadMails,
            SendMail,
            ReplyMail,
            SetMessageOption,
			SetMailboxOption,
            Logout
        }

        public Type TaskType
        {
            get;
            protected set;
        }      
    }

    public class TaskResult
    {
        public Task Task
        {
            get;
            private set;
        }

        public bool Success
        {
            get;
            private set;
        }

        public Exception Error
        {
            get;
            private set;
        }

        public object Output
        {
            get;
            private set;
        }

        public TaskResult(Task task, bool success, Exception err, object output)
        {
            this.Task = task;
            this.Success = success;
            this.Error = err;
            this.Output = output;
        }
    }

    public class CreateThreadTask : Task
    {
        public string Board
        {
            get;
            set;
        }

        public string Title
        {
            get;
            set;
        }

        public string Content
        {
            get;
            set;
        }

        public CreateThreadTask(string board, string title, string content)
        {
            this.TaskType = Type.CreateThread;

            this.Board = board;
            this.Title = title;
            this.Content = content;
        }        
    }

    public class ReplyPostTask : Task
    {
        public string Board
        {
            get;
            set;
        }

        public Post PostToReply
        {
            get;
            set;
        }

        public string ReplyTitle
        {
            get;
            set;
        }

        public string ReplyContent
        {
            get;
            set;
        }

        public string SearchCommand
        {
            get
            {
                Debug.Assert(null != PostToReply);
                Debug.Assert(null != PostToReply.Author && PostToReply.Author.Length > 0);
                Debug.Assert(null != PostToReply.Title && "" != PostToReply.Title);

                string str = "";

                str = "author=='" + PostToReply.Author + "'";

                int len = 0;
                foreach (char ch in PostToReply.Title)
                {
                    len++;
                    if (Character.NeedTwoByte(ch))
                        len++;
                }

                //str += ("&&len(title)==" + len);
                string[] ts = PostToReply.Title.Split(new char[] { '"', '\'' }, StringSplitOptions.RemoveEmptyEntries);
                if (null != ts && ts.Length > 0)
                {
                    foreach (string t in ts)
                    {
                        str += string.Format("&&sub('{0}',title)", t);
                    }
                }

                return str;
            }
        }

        public string ReplyCommand
        {
            get
            {
                return string.Format("T\r{2}\r\r{0}{1}\r", ReplyContent, 
                    Character.GetControlString(System.Windows.Forms.Keys.W, System.Windows.Forms.Keys.Control),
                    ReplyTitle);
            }
        }

        public ReplyPostTask(string board, Post post,  string reTitle, string reContent)
        {
            this.TaskType = Type.ReplyPost;

            this.Board = board;
            this.PostToReply = post;

			this.ReplyTitle = reTitle;
            this.ReplyContent = reContent;
        }
    }

    public class ReplyMailTask : Task
    {
        public Mail MailToReply
        {
            get;
            set;
        }

        public string ReplyTitle
        {
            get;
            set;
        }

        public string ReplyContent
        {
            get;
            set;
        }

        public string ReplyCommand
        {
            get 
            {
                return string.Format(
                    "T\r{0}\r\r{1}{2}\r\r\r", 
                    ReplyTitle, 
                    ReplyContent,
                    Character.GetControlString(System.Windows.Forms.Keys.W, System.Windows.Forms.Keys.Control)
                    );
            }
        }

        public ReplyMailTask(Mail mail, string title, string content)
        {
            this.TaskType = Type.ReplyMail;

            this.MailToReply = mail;
            this.ReplyTitle = title;
            this.ReplyContent = content;
        }
    }

    public class SendMailTask : Task
    {
        public string Receiver
        {
            get;
            set;
        }

        public string Title
        {
            get;
            set;
        }

        public string Content
        {
            get;
            set;
        }

        public SendMailTask(string receiver, string title, string content)
        {
            this.TaskType = Type.SendMail;

            this.Receiver = receiver;
            this.Title = title;
            this.Content = content;
        }
    }

    public class DownloadMailsTask : Task
    {
        public DateTime StartFrom
        {
            get;
            set;
        }

		public enum MailFolder
		{
			Inbox,
			Outbox
		}

		public MailFolder Folder
		{
			get;
			set;
		}

        public DownloadMailsTask(DateTime time, MailFolder folder)
        {
            this.TaskType = Type.DownloadMails;
            this.StartFrom = time;
			this.Folder = folder;
        }
    }

    public class DownloadPostsTask : Task
    {
        public string Board
        {
            get;
            set;
        }

        public string Title
        {
            get;
            set;
        }

        public string Author
        {
            get;
            set;
        }

        public SignOption Sign
        {
            get;
            set;
        }

		public Option Attach
        {
            get;
            set;
        }

		public Option Unread
        {
            get;
            set;
        }

        public DateTime StartFrom
        {
            get;
            set;
        }

        public Option OriginalPost
        {
            get;
            set;
        }

		public enum Option
		{
            NotCare,
			Yes,
			No,			
		}

        public enum SignOption
        {
            NotCare,
            M,
            G,
            B,
            MorG
        }



        public string SearchCommand
        {
            get
            {
                string str = "";
                if (null == Author || Author == "")
                {
                    str = "len(author)>0";
                }else
                {
                    str = "author=='" + Author + "'";
                }

                if (null != Title && "" != Title)
                {
                    int len = 0;
                    foreach (char ch in Title)
                    {
                        len++;
                        if (Character.NeedTwoByte(ch))
                            len++;
                    }

                    //str += ("&&len(title)=="+len);
                    string[] ts = Title.Split(new char[] { '"', '\'' }, StringSplitOptions.RemoveEmptyEntries);
                    if (null != ts && ts.Length > 0)
                    {
                        foreach (string t in ts)
                        {
                            str += string.Format("&&sub('{0}',title)", t);
                        }
                    }
                }

                switch (this.Sign)
                {
                    case SignOption.M:
                        str += "&&m";
                        break;

                    case SignOption.G:
                        str += "&&g";
                        break;

                    case SignOption.B:
                        str += "&&b";
                        break;

                    case SignOption.MorG:
                        str += "&&(m||g)";
                        break;
                }

				if (this.OriginalPost == Option.Yes)
                {
                    str += "&&(sub('Re: ',title)!=1)";
                }
                else if (this.OriginalPost == Option.No)
                {
                    str += "&&(sub('Re: ',title)==1)";
                }

                if (this.Unread == Option.Yes)
                    str += "&&unread";
				else if (this.Unread == Option .No)
					str += "&&(!unread)";

                if (this.Attach == Option.Yes)
                    str += "&&attach";
				else if (this.Attach == Option.No)
					str += "&&(!attach)";

                return str;
            }
        }

        private void Init(string board, DateTime start, string title, string author, Option origPost, SignOption sign, Option attach, Option unread)
        {
            this.TaskType = Type.DownloadPosts;
            this.Board = board;
            this.Title = title;
            this.Author = author;
            this.Sign = sign;
            this.OriginalPost = origPost;
            this.Attach = attach;
            this.Unread = unread;
            this.StartFrom = start;
        }

        public DownloadPostsTask(string board, DateTime startTime)
        {
			Init(board, startTime, "", "", Option.NotCare, SignOption.NotCare, Option.NotCare, Option.NotCare);
        }

        public DownloadPostsTask(string board, DateTime start, string title, string author, Option origPost, SignOption sign, Option attach, Option unread)
        {
            Init(board, start, title, author, origPost, sign, attach, unread);
        }
    }

    public class SetMessageOptionTask : Task
    {
        public bool AcceptMessages
        {
            get;
            set;
        }

        public SetMessageOptionTask(bool acceptMsg)
        {
            this.TaskType = Type.SetMessageOption;
            this.AcceptMessages = acceptMsg;
        }
    }

	public class SetMailboxOptionTask : Task
	{
		public bool SaveSentItemsToOutbox
		{
			get { return true; }
		}

		public SetMailboxOptionTask()
		{
			this.TaskType = Type.SetMailboxOption;
		}
	}

    public class LogoutTask : Task
    {
        public LogoutTask()
        {
            this.TaskType = Type.Logout;
        }
    }
}
